package com.dingding.configuration;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.dingding.common.BigNumberSerializer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

@Slf4j
@Configuration
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class MvcJsonConfig implements WebMvcConfigurer {

  /**
   * 全局的json objectMapper 配置，注入即可，不用每次都new
   *
   * @author DingXintao
   * @date 2023/9/13 9:24
   * @param builder
   * @param jacksonProperties
   * @return com.fasterxml.jackson.databind.ObjectMapper
   **/
  @Primary
  @Bean
  public ObjectMapper getObjectMapper(
      Jackson2ObjectMapperBuilder builder, JacksonProperties jacksonProperties) {
    ObjectMapper objectMapper = builder.createXmlMapper(false).build();
    // 全局配置序列化返回 JSON 处理
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
    simpleModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
    simpleModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
    simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(jacksonProperties.getDateFormat());
    simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
    simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
    objectMapper.registerModule(simpleModule);
    objectMapper.setTimeZone(TimeZone.getDefault());
    objectMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    log.info("初始化 jackson 配置");
    return objectMapper;
  }

}
